import requests
import threading
from typing import Iterator, Dict, Any

# --- API 配置 ---
API_HOST = "http://127.0.0.1:9880"
TTS_URL = f"{API_HOST}/tts"
CONTROL_URL = f"{API_HOST}/control" 
SAMPLE_RATE = 32000
CHUNK_SIZE = 1024

# --- 模型文件路径 (请根据你的实际路径修改) ---
GPT_MODEL_PATH = "models/雷电将军.ckpt"
SOVITS_MODEL_PATH = "models/雷电将军.pth"
ref_audio_path = r"models/雷电将军/我此番也是受神子之邀，体验一下市井游乐的氛围，和各位并无二致。.wav"
prompt_text = r"我此番也是受神子之邀，体验一下市井游乐的氛围，和各位并无二致。"

# --- TTS 请求参数模板 (已优化延迟) ---
tts_params = {
    "text": "这是一个示例文本",
    "text_lang": "zh",
    "ref_audio_path": ref_audio_path,
    "prompt_lang": "zh",
    "prompt_text": prompt_text,

    "streaming_mode": True,       # 边合成边返回
    "text_split_method": "cut0",  # 快速分句
    "speed_factor": 1.15,         # 增加语速以减少音频总时长
    
    "parallel_infer": True,       # 启用并行推理
    "batch_size": 4,              
    "batch_threshold": 0.6,
    
    "top_k": 3,                   # 降低 Top-K 采样，减少 T2S 搜索时间
    "sample_steps": 12,           # 核心优化：减少 VITS V3/V4 采样步数 (推荐 10-16)，降低 S2A 时间
    "media_type": "wav",
}

def switch_models(api_host: str, gpt_path: str, sovits_path: str) -> bool:
    """通过 API 接口切换 GPT 和 SoVITS 模型权重。"""
    print("--- 1. 正在切换 GPT 模型...")
    gpt_url = f"{api_host}/set_gpt_weights?weights_path={gpt_path}"
    try:
        response_gpt = requests.get(gpt_url, timeout=60)
        if response_gpt.status_code == 200:
            print(f"✅ GPT 模型切换成功: {gpt_path}")
        else:
            print(f"❌ GPT 模型切换失败 ({response_gpt.status_code}): {response_gpt.text}")
            return False
    except requests.exceptions.RequestException as e:
        print(f"❌ 切换 GPT 模型时连接失败: {e}")
        return False

    print("--- 2. 正在切换 SoVITS 模型...")
    sovits_url = f"{api_host}/set_sovits_weights?weights_path={sovits_path}"
    try:
        response_sovits = requests.get(sovits_url, timeout=60)
        if response_sovits.status_code == 200:
            print(f"✅ SoVITS 模型切换成功: {sovits_path}")
            return True
        else:
            print(f"❌ SoVITS 模型切换失败 ({response_sovits.status_code}): {response_sovits.text}")
            return False
    except requests.exceptions.RequestException as e:
        print(f"❌ 切换 SoVITS 模型时连接失败: {e}")
        return False

def send_tts_stop_command():
    """发送硬中断命令到 TTS 服务器的 /control 接口。"""
    try:
        response = requests.get(f"{CONTROL_URL}?command=stop", timeout=2)
        if response.status_code == 200:
             print("\n[系统] TTS服务器硬中断命令发送成功。")
        else:
             print(f"\n[系统] TTS硬中断命令发送，API返回状态码: {response.status_code}")

    except requests.exceptions.RequestException as e:
        print(f"\n[系统] ❌ 无法连接到 TTS 服务器进行硬中断: {e}")


def get_tts_audio_stream(api_url: str, params: Dict[str, Any], stop_event: threading.Event) -> Iterator[bytes]:
    """调用流式TTS接口，并通过yield返回原始音频数据块。"""
    response = None 
    try:
        response = requests.get(api_url, params=params, stream=True, timeout=30)
        
        is_hard_interrupted = response.status_code >= 400 and stop_event.is_set()
        if is_hard_interrupted:
             print(f"\n[TTS] TTS服务器因硬中断而提前终止流（状态码: {response.status_code}）。")
             return 
        
        response.raise_for_status()

        first_chunk = True
        for chunk in response.iter_content(CHUNK_SIZE):
            if stop_event.is_set():
                print("\n[TTS] TTS合成被软中断，停止接收流...")
                return
            if chunk:
                if first_chunk and len(chunk) >= 44:
                    yield chunk[44:]
                    first_chunk = False
                elif not first_chunk:
                    yield chunk
                    
    except requests.exceptions.RequestException as e:
        if not stop_event.is_set():
             print(f"\n❌ TTS 网络请求异常: {e}")
    except Exception as e:
        print(f"\n❌ 处理TTS流时发生未知错误: {e}")
    finally:
        if response:
            response.close()
